package com.woniu.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * security配置类
 * @author tarnett
 * @Configuration : 指定该类作为配置类
 * @EnableGlobalMethodSecurity : security默认不开启注解模式，开启security注解模式
 *  prePostEnabled = true : 开启权限校验（会解锁 @PreAuthorize 和 @PostAuthorize 两个注解）
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private CustomPasswordEncoder customPasswordEncoder;

    /**
     * AuthenticationManager : 认证管理接口类，security的核心接口
     * 往容器中添加认证管理接口类
     * @Bean : 用于方法上面，将方法的返回值添加到spring容器中 <bean></bean> @Service
     *  authenticationManagerBean
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 重写configure方法添加我们自定义的认证方式
     *  如：过滤的路径等
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // 关闭防止网站攻击，可能导致登录不能使用
                .csrf().disable()
                .headers().frameOptions().disable()
                .and()
                .formLogin().loginPage("/login.html")
                .failureUrl("/login.html")
                .and()
                // 过滤请求
                .authorizeRequests()
                // permitAll : 可以匿名访问的资源
                .antMatchers("/login.html", "/user/login", "/**/*.css", "/**/*.js", "/**/*.png",
                        "/swagger-resources/**", "/v3/api-docs/**", "/doc.html",
                        "/user/auth", "/user/toGiteeAuth", "/binding.html").permitAll()
                // 除了上面的请求之外，其它的所有请求都需要认证之后才能访问（登录之后才能访问）
                .anyRequest().authenticated();
                //.anyRequest().permitAll();
    }

    /**
     * 指定security的加密方式
     * @return
     */
    //@Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 指定身份认证接口，并且使用指定的加密方式
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 使用明文加密
        auth.userDetailsService(userDetailsService).passwordEncoder(customPasswordEncoder);
    }
}
